Skip to content

Update to libxmtp 3#657

Open
xmtptools wants to merge 1 commit intomainfrom
update-to-swift-bindings-1.9.0-rc2.4232e87
Open

Update to libxmtp 3#657
xmtptools wants to merge 1 commit intomainfrom
update-to-swift-bindings-1.9.0-rc2.4232e87

Conversation

@xmtptools
Copy link
Collaborator

This PR updates the iOS bindings to libxmtp version 3.

Changes:

  • Updated XMTP.podspec version to 3
  • Updated binary (LibXMTPSwiftFFI) URL and checksum in Package.swift
  • Updated Swift source file (xmtpv3.swift)

Base branch: main

@xmtptools xmtptools requested a review from a team as a code owner January 15, 2026 15:40
@claude
Copy link

claude bot commented Jan 15, 2026

Claude finished @xmtptools's task —— View job


Code Review Complete

Summary

This PR updates the iOS bindings from libxmtp 1.7.0-rc3 to version 3 (swift-bindings-1.9.0-rc2.4232e87). The update includes significant API additions and one critical breaking change that requires immediate attention.

Critical Issues

🔴 Breaking API Change - Requires Code Fix

File: Sources/XMTPiOS/Conversations.swift:87-110

The FfiMessageDeletionCallback.onMessageDeleted signature has changed:

  • Old: onMessageDeleted(messageId: Data)
  • New: onMessageDeleted(message: FfiDecodedMessage)

Current implementation (lines 87-110 in Conversations.swift):

final class MessageDeletionCallback: FfiMessageDeletionCallback {
    let callback: (Data) -> Void
    // ...
    func onMessageDeleted(messageId: Data) {
        callback(messageId)
    }
}

Impact: This code will not compile with the new bindings. The callback expects Data but now receives FfiDecodedMessage.

Required Fix: Update MessageDeletionCallback to:

final class MessageDeletionCallback: FfiMessageDeletionCallback {
    let callback: (String) -> Void  // Change to String (message ID as hex)
    
    func onMessageDeleted(message: FfiDecodedMessage) {
        callback(message.id().toHex)  // Extract ID from FfiDecodedMessage
    }
}

The public API streamMessageDeletions() already returns AsyncThrowingStream<String, Error> (line 751), so this change maintains API compatibility while fixing the internal implementation.

Test Impact: Tests in ConversationTests.swift:800 use streamMessageDeletions() and may need verification.


API Changes Analysis

New Features Added

  1. Message Preparation & Publishing (Lines 1246-1263 in xmtpv3.swift)

    • prepareMessage(contentBytes:shouldPush:) - Store messages locally before publishing
    • publishStoredMessage(messageId:) - Publish previously prepared messages
    • Enables offline message composition and batch publishing
  2. Message Deletion (Line 1203)

    • deleteMessage(messageId:) - Delete messages by ID
    • Returns deletion message ID
  3. Enhanced Permission System (Lines 9348-9445)

    • Added updateAppDataPolicy field to FfiPermissionPolicySet
    • Allows granular control over app-specific metadata updates
  4. New Content Types (Lines 10960-11063)

    • walletSendCalls (case 11)
    • markdown (case 13)
    • actions (case 14)
    • intent (case 15)
    • multiRemoteAttachment (case 16)
  5. Deleted Message Type (Lines 7196-7258, 11776-11849)

    • New FfiDeletedMessage struct
    • New FfiDeletedBy enum (.sender or .admin(inboxId:))
    • Added to FfiDecodedMessageBody and FfiDecodedMessageContent enums
  6. Metadata Field Addition (Lines 12667-12712)

    • Added appData case to FfiMetadataField enum

Removed Features

V1 Sync Metrics Removed (Lines 13593-13677)

  • Removed: v1ConsentSent, v1HmacSent, v1PayloadSent, v1PayloadProcessed
  • Reason: V2 protocol deprecated as of May 1, 2025 (per CLAUDE.md)
  • Impact: Low - these were internal metrics, not part of public API

Code Quality Assessment

✅ Strengths

  1. Generated Code Consistency: All changes follow UniFFI code generation patterns consistently
  2. Type Safety: Proper use of Swift's type system with Equatable, Hashable, Sendable conformance
  3. Memory Management: Correct FFI pointer handling with proper cleanup in deinit
  4. Error Handling: Maintains existing error handling patterns through rustCallWithError
  5. Documentation: API changes include doc comments explaining purpose

⚠️ Areas of Concern

  1. Breaking Changes Without Migration Path

    • The callback signature change has no deprecation period
    • Consider documenting this in release notes
  2. Binary Checksum Update

    • Package.swift checksum changed from e4492e8b... to 96a25317...
    • ✅ This is expected for a binary dependency update
    • ⚠️ Cannot verify binary authenticity from this PR alone
  3. Version Numbering

    • XMTP.podspec version went from 4.7.03
    • This appears to be a major version downgrade which is unusual
    • 🤔 Is this intentional? Typically versions increase monotonically

Security Considerations

✅ No Major Security Issues Detected

  1. FFI Boundary Safety: All FFI conversions use proper type checking and error handling
  2. Memory Safety: Pointer management follows Rust/Swift interop best practices
  3. No Credentials Exposed: No hardcoded secrets or keys in generated code

📋 Recommendations

  1. Binary Verification: Ensure the LibXMTPSwiftFFI.zip binary at the new URL has been security reviewed
  2. Message Deletion Security: The new deleteMessage API should be tested to ensure:
    • Proper authorization (only sender/admin can delete)
    • Deletion propagates correctly across devices
    • No orphaned data remains after deletion

Performance Considerations

Neutral to Positive Impact

  1. Message Preparation: New prepareMessage/publishStoredMessage APIs enable:

    • Reduced network calls through batching
    • Better offline support
    • Improved perceived performance
  2. Generated Code: No algorithmic changes, all FFI overhead remains constant


Test Coverage

⚠️ Testing Recommendations

  1. Critical: Test streamMessageDeletions() after fixing the callback
  2. Important: Verify new message deletion functionality
  3. Important: Test message preparation/publishing workflow
  4. Nice to have: Verify new content types are properly encoded/decoded
  5. Nice to have: Test new permission policies with app data

Existing Tests Affected

  • Tests/XMTPTests/ConversationTests.swift:800 - Uses streamMessageDeletions()
  • Any tests using MessageDeletionCallback will fail to compile

Recommendations

Before Merging

  1. 🔴 MUST FIX: Update MessageDeletionCallback in Conversations.swift (see Critical Issues above)
  2. 🟡 SHOULD VERIFY: Confirm version number change (4.7.0 → 3) is intentional
  3. 🟡 SHOULD TEST: Run ./script/run_tests.sh to verify no regressions
  4. 🟢 NICE TO HAVE: Add migration guide to release notes for the callback API change

After Merging

  1. Document the breaking change in release notes
  2. Consider adding integration tests for new message deletion features
  3. Update any documentation referencing MessageDeletionCallback

Conclusion

This is a significant upgrade that adds valuable features (message preparation, enhanced deletion, new content types) but introduces one breaking change that must be addressed before merging. The generated code quality is excellent and follows best practices. Once the MessageDeletionCallback is fixed, this PR should be safe to merge.

Recommendation: ⚠️ Request changes - Fix the breaking API change in Conversations.swift before merging.


@macroscopeapp
Copy link

macroscopeapp bot commented Jan 15, 2026

Upgrade iOS bindings to libxmtp v3 by switching LibXMTPSwiftFFI to swift-bindings-1.9.0-rc2.4232e87 and adding v3 message delete/prepare/publish APIs

Update the binary target source and checksum in Package.swift, add v3 message lifecycle APIs and deletion streaming changes in Sources/XMTPiOS/Libxmtp/xmtpv3.swift, and set spec.version to 3 in XMTP.podspec.

📍Where to Start

Start with the FFI surface changes in Sources/XMTPiOS/Libxmtp/xmtpv3.swift, focusing on FfiConversationProtocol methods and the updated FfiMessageDeletionCallback.


Macroscope summarized e910a04.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants